package work.month06.day01;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;

/**
 * @date 2020/06/01（儿童节快乐）
 * @author 王光浩
 * @need 构造方法： 
 * 			private DateHelper() ; 
 * 		  类方法： 
 * 			public DateHelper getInstance(); //用于获取一个 DateHelper对象 
 * 		  实例方法： 
 * 			根据传入的参数返回一个 Date对象 
 * 		（1）public Date toDate(int year, int month, int date, int hourOfDay, int minute, int second, int millis) 
 *      （2）public Date toDate(int year, int month, int date, int hourOfDay, int minute, int second) 
 *      （3）public Date toDate(int year, int month, int date, int hourOfDay, int minute) 
 *      	定义一个 toString方法，根据 Calendar/Date 对象，获取其表示的时间（xxxx年xx月xx日 xx:xx:xx.xxx） 
 *      （1）public String toString( final Date date ) 
 *      （2）public String toString( final Calendar date )
 *      	定义一个统计两个日期相差天数的方法
 *      （1）public int durationOfDays( Date first , Date second )
 */
public class DateHelper2 {
	private Date da = null;
	private Calendar calendar = null;
	private static DateHelper2 dateHelper = null;

	/**
	 * 构造方法
	 */
	private DateHelper2() {
		this.calendar = Calendar.getInstance();
	}

	// ------------- 类方法 --------
	/**
	 * 获取 Datehelper 对象的实例
	 * 
	 * @return
	 */
	public static DateHelper2 getInstance() {
		if (dateHelper == null)
			dateHelper = new DateHelper2();
		return dateHelper;
	}

	// ------------ 实例方法 --------

	/**
	 * 根据指定的时间值获取一个对应的 Date 对象
	 * 
	 * @param year
	 * @param month
	 * @param date
	 * @param hourOfDay
	 * @param minute
	 * @param second
	 * @param millis
	 * @return Date object
	 */
	public Date toDate(int year, int month, int date, int hourOfDay, int minute, int second, int millis) {
		this.clear();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DATE, date);
		calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
		calendar.set(Calendar.MINUTE, minute);
		calendar.set(Calendar.SECOND, second);
		calendar.set(Calendar.MILLISECOND, millis);
		return calendar.getTime();
	}

	/**
	 * 根据指定的时间值获取一个对应的 Date 对象
	 * 
	 * @param year
	 * @param month
	 * @param date
	 * @param hourOfDay
	 * @param minute
	 * @param second
	 * @return Date object
	 */
	public Date toDate(int year, int month, int date, int hourOfDay, int minute, int second) {
		return this.toDate(year, month, date, hourOfDay, minute, second, 0);
	}

	/**
	 * 根据指定的时间值获取一个对应的 Date 对象
	 * 
	 * @param year
	 * @param month
	 * @param date
	 * @param hourOfDay
	 * @param minute
	 * @return Date object
	 */
	public Date toDate(int year, int month, int date, int hourOfDay, int minute) {
		return this.toDate(year, month, date, hourOfDay, minute, 0, 0);
	}

	/**
	 * 根据传入的 Calendar对象 获取对应时间的字符串	
	 * @param date
	 * @return
	 */
	public String toString(final Calendar date) {
		StringBuilder sb = new StringBuilder();
		sb.append(date.get(Calendar.YEAR) + "年"); // 年

		int month = date.get(Calendar.MONTH) + 1;
		sb.append((month < 10 ? "0" + month : month) + "月"); // 月

		int day = date.get(Calendar.DATE);
		sb.append((day < 10 ? "0" + day : day) + "日 "); // 日

		int hour = date.get(Calendar.HOUR_OF_DAY);
		sb.append((hour < 10 ? "0" + hour : hour) + ":"); // 时

		int minute = date.get(Calendar.MINUTE);
		sb.append((minute < 10 ? "0" + minute : minute) + ":");// 分

		int second = date.get(Calendar.SECOND);
		sb.append((second < 10 ? "0" + second : second) + ":");// 秒

		int millis = date.get(Calendar.MILLISECOND); // 毫秒
		if (millis < 10)
			sb.append("00" + millis);
		else if (millis < 1000)
			sb.append("0" + millis);
		else
			sb.append(millis);
		return sb.toString();
	}

	/**
	 * 根据传入的 Calendar对象 获取对应时间的字符串	
	 * @param date
	 * @return
	 */
	public String toString(final Date date) {
		this.clear();
		calendar.setTime(date);
		return toString(calendar);
	}

	/**
	 * 计算两个 Date 时间相差的天数（将 毫秒转化为 小时，然后计算天数）
	 * @param first
	 * @param second
	 * @return
	 */
	public int durationOfDays(Date first, Date second) {
		if (first.equals(second))
			return 0;
		// 将 Date 转化为对应的 LocalDateTime
		LocalDateTime ldt1 = null;
		LocalDateTime ldt2 = null;
		ZoneId zone = ZoneId.systemDefault();
		Instant in = null;
		ZonedDateTime zdt = null;
		// 将 first 转化为 LocalDateTime对象
		in = first.toInstant();
		zdt = in.atZone(zone);
		ldt1 = zdt.toLocalDateTime();
		// 将 second 转化为 LocalDateTime对象
		in = second.toInstant();
		zdt = in.atZone(zone);
		ldt2 = zdt.toLocalDateTime();

		// DateHelper1中方法该良1，通过 java.time.Duration 类
		Duration drt = Duration.between(ldt2, ldt2);
		return (int) drt.toDays();

		// 通过 判断闰年来获取两者之间相差的天数
		LocalTime lt1 = ldt1.toLocalTime();
		LocalTime lt2 = ldt2.toLocalTime();
		int flag = lt2.isAfter(lt1) ? 1 : 0;
		LocalDate ld1 = ldt1.toLocalDate();
		LocalDate ld2 = ldt2.toLocalDate();
		int firstPart = ld1.isLeapYear() ? 366 - ld1.getDayOfYear() : 365 - ld1.getDayOfYear();
		int secondPart = ld2.getDayOfYear();
		int thirdPart = 0;
		for (int i = ld1.getYear() + 1; i < ld2.getYear(); i++) {
			if (i % 400 == 0 || (i % 4 == 0 && i % 100 != 0))
				thirdPart += 366;
			else
				thirdPart += 365;
		}
		return firstPart + secondPart + thirdPart + flag;
	}

	/**
	 * 将 Calendar对象进行清零
	 */
	private void clear() {
		calendar.clear();
	}

	public static void main(String[] args) {
		DateHelper2 dh = DateHelper2.getInstance(); // 获取 DateHelper 实例

		Date first = dh.toDate(2000, 4, 30, 5, 50); // 获取 Date 实例
		System.out.println(dh.toString(first)); // 输出 2000年05月30日 05:50:00.000

		Date second = dh.toDate(2020, 5, 1, 18, 20, 35); // 获取 Date 实例
		System.out.println(dh.toString(second)); // 输出 2020年06月01日 18:20:35.000

		int days1 = dh.durationOfDays(first, second); // 统计 first 和 second 之间间隔的天数
		System.out.println(days1);

		int days2 = dh.durationOfDays(second, first); // 统计 second 和 first 之间间隔的天数
		System.out.println(days2);
	}

}
